﻿#include<iostream>
#include <algorithm>
#include<vector>
#include <functional>
#include<map>
using namespace std;
//int main()
//{
//	int array[] = { 4,1,8,5,3,7,0,9,2,6 };
//	// 默认按照小于比较，排出来结果是升序
//	std::sort(array, array + sizeof(array) / sizeof(array[0]));
//	for (auto e : array)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//
//	// 如果需要降序，需要改变元素的比较规则(使用仿函数）
//	std::sort(array, array + sizeof(array) / sizeof(array[0]), greater<int>());
//	for (auto e : array)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	return 0;
//}

////复习之前的拷贝知识
////1.C/C+98
//int i = 0;
//const double d1 = i;     //隐式类型转换
////double& d2 = i;        //error 无法用 "int" 类型的值初始化 "double &" 类型的引用(非常量限定)	
//const double& d2 = i;
//
////2.C++98
//string str1 = "11111";    //构造匿名对象(临时变量)->拷贝构造初始化
////string& str2 = "11111"; //error 无法用 "const char [6]" 类型的值初始化 "std::string &" 类型的引用(非常量限定)	
//const string& str2 = "11111";

//struct Goods
//{
//public:
//	string _name;  // 名字
//	double _price; // 价格
//	int _evaluate; // 评价
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		,_price(price)
//		,_evaluate(evaluate)
//	{}
//};
//struct ComparePriceLess
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//struct ComparePriceGreater
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price > gr._price;
//	}
//};
//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//	for (auto e : v)
//	{
//		cout << e._name << ":"<<" " << e._price << "  " << e._evaluate<<endl;
//	}
//	cout << endl;
//
//	sort(v.begin(), v.end(), ComparePriceLess());
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//
//	sort(v.begin(), v.end(), ComparePriceGreater());
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//}


////lambda表达式举例：
//int main()
//{
//	int a = 113, b = 6;
//	//lambda表达式书写格式：[capture-list] (parameters) mutable -> return-type { statement };
//	//                    捕捉列表         参数列表      可变的     返回值类型      函数体
//	//一般是局部匿名函数，也可以写到全局
//	auto Add1 = [](int x, int y)->int {return x + y; };
//	auto Add2 = [](int x, int y)->char {return x + y; };
//
//	cout << Add1(a, b) << endl;
//	cout << Add2(a, b) << endl;
//}

//
////lambda表达式举例：
//int main()
//{
//	int a = 113, b = 6;
//	//lambda表达式书写格式：[capture-list] (parameters) mutable -> return-type { statement };
//	//                    捕捉列表         参数列表      可变的     返回值类型      函数体
//	//一般是局部匿名函数，也可以写到全局
//	//auto Add1 = [](int x, int y)->int {return x + y; };
//	//cout << Add1(a, b) << endl;
//
//	cout << "a=:" << a << " " << "b=:" << b << endl;
//	auto Swap1 = [](int& x, int& y)
//	{
//		int tmp = x;
//		x = y;
//		y = tmp;
//	};
//	Swap1(a, b);
//
//	cout <<"a=:"<< a << " " <<"b=:" << b << endl;
//}

////lambda表达式举例：
//int main()
//{
//	int a = 113, b = 6;
//	//lambda表达式书写格式：[capture-list] (parameters) mutable -> return-type { statement };
//	//                    捕捉列表         参数列表      可变的     返回值类型      函数体
//	//一般是局部匿名函数，也可以写到全局
//	//auto Add1 = [](int x, int y)->int {return x + y; };
//	//cout << Add1(a, b) << endl;
//
//	cout << "a=:" << a << " " << "b=:" << b << endl;
//	//mutable：默认情况下，lambda函数总是一个const函数，mutable可以取消其常量性。
//	//使用该修饰符时，参数列表不可省略(即使参数为空)。
//	auto Swap2 = [a,b]()mutable
//	{
//		int tmp = a;
//		a = b;
//		b = tmp;
//	};
//	Swap2();
//
//	cout << "a=:" << a << " " << "b=:" << b << endl;
//}

////lambda表达式举例：
//int main()
//{
//	int a = 113, b = 6;
//	//lambda表达式书写格式：[capture-list] (parameters) mutable -> return-type { statement };
//	//                    捕捉列表         参数列表      可变的     返回值类型      函数体
//	//一般是局部匿名函数，也可以写到全局
//	//auto Add1 = [](int x, int y)->int {return x + y; };
//	//cout << Add1(a, b) << endl;
//
//	cout << "a=:" << a << " " << "b=:" << b << endl;
//
//    //用引用的方式捕捉
//	auto Swap2 = [&a, &b]
//	{
//		int tmp = a;
//		a = b;
//		b = tmp;
//	};
//	Swap2();
//
//	cout << "a=:" << a << " " << "b=:" << b << endl;
//}

////lambda表达式举例：
//int main()
//{	
//	//lambda表达式书写格式：[capture-list] (parameters) mutable -> return-type { statement };
//	//                    捕捉列表         参数列表      可变的     返回值类型      函数体
//	int c = 9, d = 8, e = 7, f = 6, g = 5;
//	//1.传值捕捉全部对象
//	auto Func1 = [=]
//	{
//		return c - d + e * f + g;
//	};
//	cout << Func1() << endl;
//
//	//2.传引用捕捉全部对象
//	auto Func2 = [&]
//	{
//		return c * d + e * f - g;
//	};
//	cout << Func2() << endl;
//}

////lambda表达式举例：
//int main()
//{
//	//lambda表达式书写格式：[capture-list] (parameters) mutable -> return-type { statement };
//	//                    捕捉列表         参数列表      可变的     返回值类型      函数体
//	int c = 9, d = 8, e = 7, f = 6, g = 5,ret;
//	//3.混合捕捉全部对象
//	auto Func3 = [c,d,&ret]
//	{
//		ret = c + d;
//	};
//	Func3();
//	cout <<ret << endl;
//
//	//4.ret传引用捕捉,其他全部传值捕捉
//	auto Func4 = [=,&ret]
//	{
//		ret= c - d + e * f + g;
//	};
//	Func4();
//	cout << ret << endl;
//}


//struct Goods
//{
//	//结构体成员默认为公有
//	//如果是class，就需要写一个Get函数，通过Get函数访问私有成员
//
//	string _name;  // 名字
//	double _price; // 价格
//	int _evaluate; // 评价
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		, _price(price)
//		, _evaluate(evaluate)
//	{}
//};
//struct ComparePriceLess
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//struct ComparePriceGreater
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price > gr._price;
//	}
//};
//
//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//	//lambda表达式使意图简化、清晰
//	sort(v.begin(), v.end(), ComparePriceLess());
//	auto ComparePriceLess = [](const Goods& g1, const Goods& g2) {return g1._price < g2._price; };
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//	//或者直接省去对象名：ComparePriceLess。sort会自动推导类型。
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._price < g2._price; });
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._price > g2._price; });	
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._evaluate < g2._evaluate; });
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._evaluate > g2._evaluate; });
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//	return 0; 
//}

//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//
//	sort(v.begin(), v.end(), ComparePriceLess());
//	//lambda表达式简化
//	auto ComparePriceLess = [](const Goods& g1, const Goods& g2) {return g1._price < g2._price; };
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//
//
//	sort(v.begin(), v.end(), ComparePriceGreater());
//	for (auto e : v)
//	{
//		cout << e._name << ":" << " " << e._price << "  " << e._evaluate << endl;
//	}
//	cout << endl;
//}

//void (*PF)();
//int main()
//{
//	auto f1 = [] {cout << "hello world" << endl; };
//	auto f2 = [] {cout << "hello world" << endl; };
//	
//    //f1 = f2;   // 编译失败--->提示找不到operator=() 。lambda底层其实是一个仿函数
//	
//	// 允许使用一个lambda表达式拷贝构造一个新的副本
//	auto f3(f2);
//	f3();
//	// 可以将lambda表达式赋值给相同类型的函数指针
//	PF = f2;
//	PF();
//	return 0;
//}


//class Rate
//{
//public:
//	Rate(double rate) : _rate(rate)
//	{}
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//private:
//	double _rate;
//};
//int main()
//{
//	// 函数对象
//	double rate = 0.49;
//	Rate r1(rate);
//	r1(10000, 2);
//	// lamber
//	auto r2 = [=](double monty, int year)->double {return monty * rate * year;
//	};
//	r2(10000, 2);
//	return 0;
//}
//
////ret = func(x);
//// 上面func可能是什么呢？那么func可能是函数名？函数指针？函数对象(仿函数对象)？也有可能
////是lamber表达式对象？所以这些都是可调用的类型！如此丰富的类型，可能会导致模板的效率低下！
////为什么呢？我们继续往下看
//template<class F, class T> T useF(F f, T x)
//{
//	static int count = 0;
//	cout << "count:" << ++count << endl;
//	cout << "count:" << &count << endl;
//	return f(x);
//}
//double f(double i) 
//{
//	return i / 2;
//}
//struct Functor
//{
//	double operator()(double d)
//	{
//		return d / 3;
//	}
//};
//int main()
//{
//	// 函数名
//	cout << useF(f, 11.11) << endl;
//	// 函数对象
//	cout << useF(Functor(), 11.11) << endl;
//	// lamber表达式
//	cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;
//	return 0;
//}

//// 使用方法如下：
//#include <functional>
//int f(int a, int b)
//{
//	return a + b;
//}
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//class Plus
//{
//public:
//	//静态的包装后就能用
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//	//非静态的含有this指针，包装后需要加上类名
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//int main()
//{
//	// 函数名(函数指针)
//	std::function<int(int, int)> func1 = f;
//	cout << func1(1, 2) << endl;
//	// 函数对象
//	std::function<int(int, int)> func2 = Functor();
//	cout << func2(1, 2) << endl;
//	// lamber表达式
//	std::function<int(int, int)> func3 = [](const int a, const int b)
//	{return a + b; };
//	cout << func3(1, 2) << endl;
//
//	// 类的成员函数
//	std::function<int(int, int)> func4 = &Plus::plusi;
//	cout << func4(1, 2) << endl;
//	std::function<double(Plus, double, double)> func5 = &Plus::plusd;
//	cout << func5(Plus(), 1.1, 2.2) << endl;
//	return 0;
//}


//// 使用举例
//#include <functional>
//int Plus(int a, int b)
//{
//	return a + b;
//}
//class Sub
//{
//public:
//	int sub(int a, int b)
//	{
//		return a - b;
//	}
//};
//int main()
//{
//	//表示绑定函数plus 参数分别由调用 func1 的第一，二个参数指定
//	std::function<int(int, int)> func1 = std::bind(Plus, placeholders::_1,placeholders::_2);
//	//auto func1 = std::bind(Plus, placeholders::_1, placeholders::_2);
//	
//	//func2的类型为 function<void(int, int, int)> 与func1类型一样
//	//表示绑定函数 plus 的第一，二为： 1， 2
//	auto  func2 = std::bind(Plus, 1, 2);
//	cout << func1(1, 2) << endl;
//	cout << func2() << endl;
//	Sub s;
//	// 绑定成员函数
//	std::function<int(int, int)> func3 = std::bind(&Sub::sub, s,
//		placeholders::_1, placeholders::_2);
//	// 参数调换顺序
//	std::function<int(int, int)> func4 = std::bind(&Sub::sub, s,
//		placeholders::_2, placeholders::_1);
//	cout << func3(1, 2) << endl;
//	cout << func4(1, 2) << endl;
//	return 0;
//}


#include <functional>
int f(int a, int b)
{
	return a - b;
}
struct Functor
{
public:
	int operator() (int a, int b)
	{
		return a + b;
	}
};
class Plus
{
public:
	Plus(int x=2)
		:_x(x)
	{}

    int plusi(int a, int b)
	{
		return (a + b)*_x;
	}
private:
	int _x;
};
int main()
{
	// 函数名(函数指针)
	std::function<int(int, int)> func1 = f;
	cout << "func1(1, 2)：\t\t" << func1(1, 2) << endl;

	//bind调整顺序
	std::function<int(int, int)> func6 = std::bind(f, placeholders::_2, placeholders::_1);
	cout << "func6(1, 2)：\t\t" << func6(1, 2) << endl;

	// 函数对象
	std::function<int(int, int)> func2 = Functor();
	cout << "func2(10, 20)：\t\t" << func2(10, 20) << endl;
	
	//1.直接包装的是3个参数
	std::function<int(Plus, int, int)> func3 = &Plus::plusi;
	cout << "func3(Plus(), 100, 200)：" << func3(Plus(), 100, 200) << endl;

	//2.1 bind绑定，调整了个数，为2个参数
	std::function<int(int, int)> func4 = std::bind(&Plus::plusi,Plus(10),
		placeholders::_1,placeholders::_2);
	//第一个对象Plus(10)已经绑死，后面两个对象占位placeholders::_1,placeholders::_2是显式传参，占位
	cout << "func4(100, 200)：\t" << func4(100, 200) << endl;

	//2.2 bind绑定，调整了个数，为1个参数
	std::function<int(int)> func5 = std::bind(&Plus::plusi, Plus(10),15, placeholders::_1);
	//第一个Plus(10)、第二个对象15已经绑死，后面一个对象占位placeholders::_1是显式传参，占位
	cout << "func5(200)：\t" << func5(200) << endl;


	map<string, std::function<int(int, int)>> opFuncMap =
	{
		{"普通函数指针",f},
		{"函数对象",Functor()},
		{"成员函数指针",std::bind(&Plus::plusi,Plus(10),
		placeholders::_1,placeholders::_2)}
	};
	cout << "普通函数指针(1, 2)：\t" << opFuncMap["普通函数指针"](1, 2) << endl;
	cout << "函数对象(1, 2)：\t" << opFuncMap["函数对象"](1, 2) << endl;
	cout << "成员函数指针(1, 2)：\t" << opFuncMap["成员函数指针"](1, 2) << endl;

	return 0;
}
